import React, { Suspense }from 'react';
import { Spin } from 'antd';
import { Routes, Route, Navigate } from 'react-router-dom';

import ErrorPage from '@/pages/ErrorPage';

// 加载路由文件生成路由配置
const loadRoutes = (files: __WebpackModuleApi.RequireContext) => files.keys().reduce((arr, key) => {
  const routes = files(key).default;
  return typeof routes === 'object' ? arr.concat(routes) : arr;
}, []).sort((prev: { sort: number }, next: { sort: number }) => {
  return prev.sort - next.sort // 根据sort 排序(如果有)
});
// require.context('读取文件的路径', 是否遍历文件的子目录, 匹配文件的正则)
  // webpack的api, 获取一个特定的上下文, 主要用来实现自动化导入模块
  // 可以从一个文件夹引入很多模块, 它会遍历文件夹中的指定文件, 然后自动导入, 就不需要每次显式的调用import导入模块
  // 函数执行后返回的是一个函数, 并且这个函数有3个属性
    // resolve {Function}: 接受一个参数request, request为test文件夹下面匹配文件的相对路径, 返回这个匹配文件相对于整个工程的相对路径
    // keys {Function}: 返回匹配成功模块的名字组成的数组
    // id {String}: 执行环境的id, 返回的是一个字符串, 主要用在module.hot.accept,  热加载
const configRoutes = loadRoutes(require.context('./routes', false, /\.ts|\.tsx$/));

// 递归实现嵌套子路由
const getNeatSubRoute = (routesArr: Array<any>) => {
  return routesArr.map((item: any) => {
    const { children, path, element: MyElement } = item;
    if(children) {
      return (
        <Route key={path} path={path} element={<MyElement />} >
          {getNeatSubRoute(children)}
        </Route>
      );
    };
    return <Route key={path} path={path} element={<MyElement />} />;
  });
};

// 获取路由配置
const RouteConfig: React.FunctionComponent<{}> = () => {
  return (
    <Suspense fallback={<Spin />}>
      <Routes>
        {getNeatSubRoute(configRoutes)}
        {/* 重定向 */}
        <Route path='/' element={<Navigate to='/introduction' />} />
        <Route path='*' element={<ErrorPage />} />
      </Routes>
    </Suspense>
  );
};

export {
  RouteConfig,
  configRoutes,
}